package com.example.joke.base.ioc;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.view.View;
import android.widget.Toast;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ViewUtils {

    public static void inject(Activity activity) {
        inject(new ViewFinder(activity), activity);
    }

    public static void inject(View view) {
        inject(new ViewFinder(view), view);
    }

    public static void inject(View view, Object object) {
        inject(new ViewFinder(view), object);
    }

    // 兼容 上面三个方法，object --〉反射需要执行的类
    private static void inject (ViewFinder finder, Object object){

        injectFiled(finder, object);

        injectEvent(finder, object);

    }
    // 注入事件
    private static void injectEvent(ViewFinder finder, Object object) {
        // 1.获取类里面所有的方法
        Class<?> clazz = object.getClass();
        // 获取所有方法包括私有和公有
        Method[] methods = clazz.getMethods();
        // 2.获取OnClick里面的value值
        for (Method method : methods) {
            OnClick onClick = method.getAnnotation(OnClick.class);
            if (onClick != null) {
                int value[] = onClick.value();
                for (int i : value) {
                    // 3.findViewById 找到View
                    View view = finder.findViewById(i);
                    // 网络检测功能，若没网则不执行点击事件具体逻辑return
                    boolean checkNet = method.getAnnotation(CheckNet.class) != null;
                    if (view != null) {
                        // 4.设置view.setOnClickListener
                        view.setOnClickListener(new DeclaredOnClickListener(object, method, checkNet));
                    }
                }
            }
        }
    }

    private static class DeclaredOnClickListener implements View.OnClickListener {

        private Object object;
        private Method method;
        private boolean checkNet;

        public DeclaredOnClickListener(Object object, Method method, boolean checkNet) {
            this.object = object;
            this.method = method;
            this.checkNet = checkNet;
        }

        @Override
        public void onClick(View v) {
            // 需不需要检测网络
            if (checkNet) {
                // 需要
                if (!networkAvailable(v.getContext())){
                    // 打印Toast"亲，您的网络不太给力” 写死有点问题,需要配置
                    Toast.makeText(v.getContext(),"亲，您的网络不太给力",Toast.LENGTH_LONG).show();
                    return;
                }
            }

            // 点击会调用方法
            try {
                // 所有方法都可以，包括私有公有
                method.setAccessible(true);
                // 5.反射执行方法
                method.invoke(object, v);
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    // 5.反射执行方法
//                    method.invoke(object, null);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    // 注入属性
    private static void injectFiled(ViewFinder finder, Object object) {
        //1、获取类里面所有的属性
        Class<?> clazz = object.getClass();
        // 获取所有属性包括私有和共有
        Field[] fields = clazz.getDeclaredFields();

        // 2.获取ViewById的里面的value值
        for (Field field :fields){
            ViewById viewById = field.getAnnotation(ViewById.class);
            // 防止没有注解的属性
            if(viewById != null){
                // 获取注解里面的id值->R.id.test_tv
                int viewId = viewById.value();
                // 3. findViewById 找到View
                View view = finder.findViewById(viewId);
                // 防止id写错，找不到
                if (view != null) {
                    // 能够注入所有修饰符private public
                    field.setAccessible(true);
                    //4.动态的注入找到的View
                    try{
                        field.set(object, view);
                    } catch (IllegalAccessException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    private static boolean networkAvailable(Context context){
        // 得到连接管理器对象
        try {
            ConnectivityManager connectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
